import type LayerModelSimple from '../../LayerModel/LayerModelSimple'
import { GeoView } from '../../type/GeoType'
import MapUtil from '../../utils/MapUtil'
import { Viewer, Ellipsoid, Cartesian2, Cartesian3 } from 'cesium'
import ResolutionUtil from './ResolutionUtil'

/**
 * @ClassName CesiumViewerUtil
 * @Description Leaflet地图工具
 * @Author xuyizhuo
 * @Date 2023/11/16 22:14
 */
export default class CesiumViewerUtil extends MapUtil<Viewer> {
    /**
     * 加载地图服务
     * @returns {}
     */
    addService(): LayerModelSimple<Viewer> {
        return {} as LayerModelSimple<Viewer>
    }

    /**
     * 获取地图视角
     * @returns {}
     */
    getMapView(): GeoView {
        // 通过相机参数计算 地图比例尺、中心点
        const { scene, camera } = this.realMap
        const canvas = scene.canvas
        const mapWindow = [canvas.clientWidth, canvas.clientHeight]
        if (mapWindow[0] <= 0 || mapWindow[1] <= 0) {
            const container = this.realMap.container
            mapWindow[0] = container.clientWidth
            mapWindow[1] = container.clientHeight
        }
        // 1、获取当前地图的中心点的窗口像素坐标，在通过场景拾取为Cesium三维笛卡尔坐标，再换算为弧度坐标，最后转为经纬度坐标
        const clientCenter = new Cartesian2(mapWindow[0] / 2, mapWindow[1] / 2)
        console.log('clientCenter', clientCenter)
        const ray = scene.camera.getPickRay(clientCenter) || {
            direction: new Cartesian3(0, 0, 0),
            origin: new Cartesian3(0, 0, 0),
        }
        console.log('ray', ray)
        const positionCartesian3 = scene.globe.pick(ray, scene) || new Cartesian3(0, 0, 0)
        const ellipsoid = Ellipsoid.WGS84
        const positionCartographic = ellipsoid.cartesianToCartographic(positionCartesian3)
        // 得到地图中心点经纬度坐标
        const centerPosition = [
            (positionCartographic.longitude * 180) / Math.PI,
            (positionCartographic.latitude * 180) / Math.PI,
        ]

        // 2、计算距离：利用地图分辨率计算地图缩放层级zoom
        const distance = Cartesian3.distance(positionCartesian3, camera.position)
        const latitude = positionCartographic ? positionCartographic.latitude : 0
        // 计算地图分辨率
        const resolution = ResolutionUtil.calcResolutionForDistance(distance, latitude, scene)
        // 根据分辨率计算地图层级
        const zoom = ResolutionUtil.getZoomForResolution(resolution)
        return {
            x: centerPosition[0],
            y: centerPosition[1],
            z: zoom,
        }
    }

    /**
     * 飞行到视角
     * @param {GeoView} geoView 视角信息
     * @returns {CesiumViewerUtil}
     */
    flyToView(geoView: GeoView): CesiumViewerUtil {
        // 设置地图中心点和层级
        const { x, y, z } = geoView
        // // 高度计算有误差
        // const distance = (6371000 * Math.cos((y * Math.PI) / 180)) / 2 ** (z - 4.5)

        const resolution = ResolutionUtil.getResolutionForZoom(z)
        // 通过分辨率计算相机高度
        const distance = ResolutionUtil.calcDistanceForResolution(resolution, ResolutionUtil.toRadians(y), this.realMap, 1)
        // console.log('相机距离', distance)

        // 根据位置、相机高度定位
        this.realMap.camera.flyTo({
            destination: Cartesian3.fromDegrees(x, y, distance),
        })
        return this
    }
}
